.NET6 C#, LineBot, Line Messaging API, C#, dotnet core
Hello 各位好,今天這篇要介紹 flex message 正是讓 Line Bot 成為現今如此熱門的行銷管道的一大要素,正如 "flex" 字面上的意思,開發者能夠相當程度上的客製化訊息的格式,並且也能做出 carousel 的輪播效果,所以開發者能夠將 Line Bot 依照要提供的服務不同,創造出獨特的風格與服務內容,不會像早期的 Line Bot,因為大家都使用相同的訊息格式導致 各個 Line Bot 之間的特色並不鮮明。
Flex 訊息格式設定的方式與 CSS Flexible Box 相似,但因為屬性實在太多,所以詳細的內容還是去Line官方文件內查看,這邊就先做個簡單的介紹後,透過實作來讓大家感受一下Flex的效果!
Flex Message 由 Container 與 Component 組成
Box : Bubble 中 layout 的基本單位,Box 中可以放入其他的 component,其作用是定義在他之下的 child component 的 layout 方式,並起到不同 layout 之間區隔的作用。
詳細資料請參考 : 文件連結
Button : Button 元件一樣是被點擊後會執行設定好的Action。
詳細資料請參考 : 文件連結
Image : 用來顯是圖片的元件,比較特別的是 image component 還可以設定放入動畫圖片。
詳細資料請參考 : 文件連結
Video : 播放影片的元件,但使用 video component 有以下限制
Icon : 用於在文字前方標示圖案的元件,但其只能放在 layout 設為 baseline 的 box component 中使用。
詳細資料請參考 : 文件連結
Text : 顯示文字的元件。
詳細資料請參考 : 文件連結
Span : 也是用於顯示文字的元件,不過必須放在 text component 的 content 屬性中,每個 span 都可以設定自己的字體樣式,達到一個 text component 中有多種字體樣式的效果。
詳細資料請參考 : 文件連結
Separator : 在 box component 中劃出一條線的元件,用於幫元件做分割,在水平 layout 的 box 中會畫出垂直線,在垂直 layout 的 box 中會畫出水平線。
詳細資料請參考 : 文件連結
Filler : 在元件與元件之間做出空白的區隔。
詳細資料請參考 : 文件連結
在 MessageEnum.cs 中新增 Enum
public static class FlexContainerTypeEnum
{
public const string Bubble = "bubble";
public const string Carousel = "carousel";
}
在 Dtos/Messages 中宣告 FlexMessageDto.cs
using LineBotMessage.Enum;
namespace LineBotMessage.Dtos
{
public class FlexMessageDto<T> : BaseMessageDto
{
public FlexMessageDto()
{
Type = MessageTypeEnum.Flex;
}
public string AltText { get; set; }
public T Contents { get; set; }
}
// containers
public class FlexBubbleContainerDto
{
public string Type { get; set; } = FlexContainerTypeEnum.Bubble;
public string? Size { get; set; }
public string? Direction { get; set; }
public FlexComponentDto? Header { get; set; }
public FlexComponentDto? Hero { get; set; }
public FlexComponentDto? Body { get; set; }
public FlexComponentDto? Footer { get; set; }
public FlexComponentDto? Style { get; set; }
public ActionDto? Action { get; set; }
}
public class FlexCarouselContainerDto
{
public string Type { get; set; } = FlexContainerTypeEnum.Carousel;
public List<FlexBubbleContainerDto> Contents { get; set; }
}
// component
public class FlexComponentDto
{
public string Type { get; set; }
// box component
public string? Layout { get; set; }
public List<FlexComponentDto>? Contents { get; set; }
public string? BackgroundColor { get; set; }
public string? BorderColor { get; set; }
public string? BorderWidth { get; set; }
public string? CornerRadius { get; set; }
public string? Width { get; set; }
public string? MaxWidth { get; set; }
public string? Height { get; set; }
public string? MaxHeight { get; set; }
public int? Flex { get; set; }
public string? Spacing { get; set; }
public string? Mergin { get; set; }
public string? PaddingAll { get; set; }
public string? PaddingTop { get; set; }
public string? PaddingBottom { get; set; }
public string? PaddingStart { get; set; }
public string? PaddingEnd { get; set; }
public string? Position { get; set; }
public string? OffsetTop { get; set; }
public string? OffsetBottom { get; set; }
public string? OffsetStart { get; set; }
public string? OffsetEnd { get; set; }
public ActionDto? Action { get; set; }
public string? JustifyContent { get; set; }
public string? AlignItems { get; set; }
public FlexBackgroundDto? Background { get; set; }
// button coponent
public string? Style { get; set; }
public string? Color { get; set; }
public string? Gravity { get; set; }
public string? AdjustMode { get; set; }
//image component
public string? Url { get; set; }
public string? Align { get; set; }
public string? Size { get; set; }
public string? AspectRatio { get; set; }
public string? AspectMode { get; set; }
public bool? Animated { get; set; }
//video component
public string? PreviewUrl { get; set; }
public string? AltContent { get; set; }
//text component
public string? Text { get; set; }
public bool? Wrap { get; set; }
public string? LineSpaceing { get; set; }
public int? Maxlines { get; set; }
public string? Weight { get; set; }
public string? Decoration { get; set; }
public string? Margin { get; set; }
//icon, span, separator, filler 這四個元件所需屬性已在上面宣告過,故不用重複宣告
}
public class FlexBackgroundDto
{
public string? Type { get; set; }
public string? Angle { get; set; }
public string? StartColor { get; set; }
public string? EndColor { get; set; }
public string? CenterColor { get; set; }
public string? CenterPosition { get; set; }
}
// bubble container styles
public class FlexBubbleContainerStyle
{
public FlexBlockStyle? Header { get; set; }
public FlexBlockStyle? Hero { get; set; }
public FlexBlockStyle? Body { get; set; }
public FlexBlockStyle? Footer { get; set; }
}
public class FlexBlockStyle
{
public string? BackgroundColor { get; set; }
public bool? Separator { get; set; }
public string? SeparatorColor { get; set; }
}
}
看到上面的宣告就知道,Flex 的製作非常複雜,若要使用程式內 class 傳送的方式實在太複雜,也沒辦法對訊息有畫面參考,所以 Line 有提供 Flex Simulator,能夠快速的製作出 flex,並產相對應的 Json 字串。
畫面中有三區塊,分別是
按下右上角 Send 按鈕後也可以將目前製作的 flex 透過這支機器人傳送給你實際參考(第一次傳送時會要求將此機器人加為好友)。
右上角的 Showcase 內有許多 Line 提供的 flex 範例,這次測試就選擇一個自己喜歡的範例吧。
選好範例後按下 View as JSON 即可展開以下畫面,這些就是目前訊息的 Json 字串。
這次測試就使用 廣播的 API 吧!
public const string FlexBubble = "flexBubble";
public const string FlexCarousel = "flexCarousel";
case MessageTypeEnum.FlexBubble:
messageRequest = _jsonProvider.Deserialize<BroadcastMessageRequestDto<FlexMessageDto<FlexBubbleContainerDto>>>(strBody);
break;
case MessageTypeEnum.FlexCarousel:
messageRequest = _jsonProvider.Deserialize<BroadcastMessageRequestDto<FlexMessageDto<FlexCarouselContainerDto>>>(strBody);
break;
Swagger 廣播 API 畫面
測試用 JSON Body
{
"Messages": [
{
"Type": "flex",
"AltText": "This is flex message",
"Contents": //這裡放 flex simulator 產生的 JSON
}
]
}
Flex 介紹結束後,就把 Line Bot 目前所有訊息格式介紹完了,目前的這些內容串連起來就能夠打造出一個內容豐富的 Line Bot,尤其是使用 flex 的訊息,才能夠讓 Line Bot 變得與眾不同。
下一篇開始會介紹 Line Bot 的 rich menu, rich menu 是顯示在 Line Bot 聊天室下方的選單,與 Image map 一樣是提供一張圖片後對圖片做區塊的分割,並設定點選後執行的動作,下一篇見!
如果想要參考今天範例程式碼的部份,下面是 Git Repo 連結,方便大家參考。
你好,我想請教一下
當FlexMessage需要客製化的時候
例如: "text": "Brown Cafe" => "text": "Hello"
是不是還是要走FlexMessageDto.cs新建class方式去會比較好嗎?
因為以下這種方式會變成要用Replace的方式改Json內容
{
"Messages": [
{
"Type": "flex",
"AltText": "This is flex message",
"Contents": //這裡放 flex simulator 產生的 JSON
}
]
}
還是版大有還有什麼比較好維護FlexMessage的方式嗎
這問題困擾我很久
在回答問題之前,先說明一下 目前手邊運作的機制 ~
Controller裏回傳資料的方式,是直接回傳自定義好的Model物件
而 JsonProvider 會依設定的格式自動先轉成對應的 json 再回傳給 line api
如果是依上述的說明,來回答上述的問題(FlexMessage需要客製化)
那就是 Model 物件裏的文字屬性(相對應的屬性) 修改
myDataModel.Contents = "新的內容";
然後 return myDataModel 即可~
(*如果是要用 replace json裏面的內容,感覺會很可怕 ~ 如果寫不小心,資料格式整個就會錯亂 !!!)
真的很謝謝你!!
我大概知道怎麼做比較好了
你好,想請問一下LineBotMessage.Dtos 的FlexComponentDto class
有段註解說icon, span, separator, filler 屬性已宣告過
可是我在其餘地方都沒有看到
想問這個地方是什麼意思,不太了解?
再請解惑
這段註解的意思是,「icon, span, separator, filler」這四個元件所需要的屬性已經包含在上面了,所以用註解表示不用重複宣告。
不過剛剛去翻了一下官方文件發現有出現新的屬性,目前有補上 margin,如果有其他遺漏的新屬性歡迎再通知我更新。
真的感謝回復